//
// Created by haoy on 2017/3/10.
//

#ifndef ANALYZER_DBG_HPP
#define ANALYZER_DBG_HPP

#include <iomanip>
#include <iostream>
#include <log4cplus/clogger.h>
#include <log4cplus/loggingmacros.h>
#include <string>
#include <sstream>

#define dbgd(...) log4cplus_logger_log(NULL, L4CP_DEBUG_LOG_LEVEL, __VA_ARGS__)
#define dbgv(...) log4cplus_logger_log(NULL, L4CP_TRACE_LOG_LEVEL, __VA_ARGS__)
#define dbgi(...) log4cplus_logger_log(NULL, L4CP_INFO_LOG_LEVEL, __VA_ARGS__)
#define dbgw(...) log4cplus_logger_log(NULL, L4CP_WARN_LOG_LEVEL, __VA_ARGS__)
#define dbge(...) log4cplus_logger_log(NULL, L4CP_ERROR_LOG_LEVEL, __VA_ARGS__)

#define FMT_DEBUG(event, fmt) LOG4CPLUS_DEBUG("", event << fmt)
#define FMT_INFO(event, fmt) LOG4CPLUS_INFO("", event << fmt)
#define FMT_WARN(event, fmt) LOG4CPLUS_WARN("", event << fmt)
#define FMT_ERROR(event, fmt) LOG4CPLUS_ERROR("", event << fmt)

class FMT {
public:
    FMT() {
        _oss << std::boolalpha;
    }

    FMT(const FMT& other) {
        _oss << std::boolalpha;
        _oss << other._oss.str();
    }

//    FMT(std::ostringstream& oss) {
//
//        _oss << oss.str();
//    }

    template <class T>
    FMT kv(const std::string& name, const T &value) {
        FMT fmt(*this);
        fmt._oss << "[" << name << "=" << value << "]";
        return fmt;
    }

    template <class T>
    FMT v(const T &value) {
        FMT fmt(*this);
        fmt._oss << "[" << value << "]";
        return fmt;
    }

private:
    friend std::ostream &operator<<(std::ostream &os, const FMT& fmt) {
        return os << fmt._oss.str();
    }

    std::ostringstream _oss;
};

extern std::ostream &operator<<(std::ostream &os, const FMT& fmt);

#endif //ANALYZER_DBG_HPP
